package com.hxd.common.config;

import java.util.List;

import javax.servlet.MultipartConfigElement;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.unit.DataSize;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.hxd.common.core.spring.AuthenticationInterceptor;

@Configuration
public class WebConfig implements WebMvcConfigurer {
	
	@Bean
    public AuthenticationInterceptor securityInterceptor() {
        return new AuthenticationInterceptor();
    }

	@SuppressWarnings("deprecation")
	@Override
	public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
		WebMvcConfigurer.super.configureContentNegotiation(configurer);
		configurer.favorPathExtension(false);
	}
	
	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
		builder.serializationInclusion(JsonInclude.Include.ALWAYS);
		ObjectMapper mapper = builder.build();
		SimpleModule simpleModule = new SimpleModule();
		// Long -> String
		simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
		mapper.registerModule(simpleModule);
		// 忽略 transient 修饰的属性
		mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
		converters.add(0, new MappingJackson2HttpMessageConverter(mapper));
		WebMvcConfigurer.super.configureMessageConverters(converters);
	}
	
	
	@Override
    public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(securityInterceptor()).addPathPatterns("/**").excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
    }
		
	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**")
				.allowCredentials(true)
				.allowedOriginPatterns("*")
				.allowedHeaders("*")
				.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
				.maxAge(3600);
	}
	
	@Bean
	public MultipartConfigElement multipartConfigElement (
			@Value("${multipart.maxFileSize}") String maxFileSize,
			@Value("${multipart.maxRequestSize}") String maxRequestSize) {
		MultipartConfigFactory factory = new MultipartConfigFactory();
		// 单个文件最大
		factory.setMaxFileSize(DataSize.ofGigabytes(1));
		// 设置总上传数据总大小
		factory.setMaxRequestSize(DataSize.ofGigabytes(2));
		return factory.createMultipartConfig();
	}
    
}
